const express = require('express');
const path = require('path');
const fs = require('fs').promises;
const database = require('../database/init');

const app = express();
app.use(express.json({ limit: '50mb' }));

// 用户会话存储
const sessions = new Map();

// 身份验证中间件
const auth = async (req, res, next) => {
    const authHeader = req.headers.authorization;
    if (!authHeader) {
        return res.status(401).json({ error: 'No authorization header' });
    }

    try {
        const [username, password] = Buffer.from(authHeader.split(' ')[1], 'base64')
            .toString()
            .split(':');

        const user = await database.validateUser(username, password);
        if (!user) {
            return res.status(401).json({ error: 'Invalid credentials' });
        }

        req.user = user;
        next();
    } catch (error) {
        res.status(500).json({ error: 'Authentication error' });
    }
};

// 获取当前工作目录
const getCurrentDir = (req) => {
    const sessionId = req.headers['session-id'];
    return sessions.get(sessionId) || req.user.root_path;
};

// 确保路径在用户根目录下
const isPathSafe = (rootPath, targetPath) => {
    const relativePath = path.relative(rootPath, targetPath);
    return relativePath && !relativePath.startsWith('..') && !path.isAbsolute(relativePath);
};

// API 路由
app.get('/api/pwd', auth, (req, res) => {
    const currentDir = getCurrentDir(req);
    res.json({ path: currentDir });
});

app.post('/api/cd', auth, (req, res) => {
    const { path: targetPath } = req.body;
    const sessionId = req.headers['session-id'];
    
    if (!isPathSafe(req.user.root_path, targetPath)) {
        return res.status(403).json({ error: 'Access denied' });
    }
    
    sessions.set(sessionId, targetPath);
    res.json({ path: targetPath });
});

app.post('/api/upload', auth, async (req, res) => {
    try {
        const { filename, content } = req.body;
        const currentDir = getCurrentDir(req);
        const filePath = path.join(currentDir, filename);
        
        if (!isPathSafe(req.user.root_path, filePath)) {
            return res.status(403).json({ error: 'Access denied' });
        }

        await fs.writeFile(filePath, Buffer.from(content, 'base64'));
        res.json({ message: 'File uploaded successfully' });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

app.get('/api/download/:filename', auth, async (req, res) => {
    try {
        const currentDir = getCurrentDir(req);
        const filePath = path.join(currentDir, req.params.filename);
        
        if (!isPathSafe(req.user.root_path, filePath)) {
            return res.status(403).json({ error: 'Access denied' });
        }

        const content = await fs.readFile(filePath);
        res.json({ content: content.toString('base64') });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

app.delete('/api/file/:filename', auth, async (req, res) => {
    try {
        const currentDir = getCurrentDir(req);
        const targetPath = path.join(currentDir, req.params.filename);
        
        if (!isPathSafe(req.user.root_path, targetPath)) {
            return res.status(403).json({ error: 'Access denied' });
        }

        const stats = await fs.stat(targetPath);
        if (stats.isDirectory()) {
            await fs.rm(targetPath, { recursive: true });
        } else {
            await fs.unlink(targetPath);
        }
        
        res.json({ message: 'Deleted successfully' });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

app.put('/api/file/:oldname/:newname', auth, async (req, res) => {
    try {
        const currentDir = getCurrentDir(req);
        const oldPath = path.join(currentDir, req.params.oldname);
        const newPath = path.join(currentDir, req.params.newname);
        
        if (!isPathSafe(req.user.root_path, oldPath) || !isPathSafe(req.user.root_path, newPath)) {
            return res.status(403).json({ error: 'Access denied' });
        }

        await fs.rename(oldPath, newPath);
        res.json({ message: 'Renamed successfully' });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

app.post('/api/mkdir', auth, async (req, res) => {
    try {
        const { dirname } = req.body;
        const currentDir = getCurrentDir(req);
        const dirPath = path.join(currentDir, dirname);
        
        if (!isPathSafe(req.user.root_path, dirPath)) {
            return res.status(403).json({ error: 'Access denied' });
        }

        await fs.mkdir(dirPath);
        res.json({ message: 'Directory created successfully' });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

app.get('/api/list', auth, async (req, res) => {
    try {
        const currentDir = getCurrentDir(req);
        const files = await fs.readdir(currentDir, { withFileTypes: true });
        
        const contents = await Promise.all(files.map(async (file) => ({
            name: file.name,
            type: file.isDirectory() ? 'directory' : 'file'
        })));
        
        res.json(contents);
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

// 初始化数据库并启动服务器
const PORT = process.env.PORT || 8080;
database.init()
    .then(() => {
        app.listen(PORT, () => {
            console.log(`Server running on port ${PORT}`);
        });
    })
    .catch((error) => {
        console.error('Failed to initialize database:', error);
        process.exit(1);
    });